package edu.univercidade.tcc.server.config;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import edu.univercidade.tcc.server.model.IssueStatus;
import edu.univercidade.tcc.server.model.Permission;
import edu.univercidade.tcc.server.model.Priority;
import edu.univercidade.tcc.server.model.ProjectRole;
import edu.univercidade.tcc.server.model.Tracker;
import edu.univercidade.tcc.server.model.Workflow;

@Component
public class SapDefaultEntitiesLoader implements ApplicationListener<ContextRefreshedEvent> {

	private Map<String, Permission> permissionMap = new HashMap<String, Permission>();
	private Map<String, IssueStatus> statusMap = new HashMap<String, IssueStatus>();
	private Map<String, Tracker> trackerMap = new HashMap<String, Tracker>();
	private Map<String, ProjectRole> roleMap = new HashMap<String, ProjectRole>();
	private static final Logger LOGGER = Logger.getLogger("Startup");

	@Override
	@Transactional
	public void onApplicationEvent(ContextRefreshedEvent event) {
		LOGGER.setLevel(Level.ALL);
		if (event.getApplicationContext().getParent() == null) {
			LOGGER.info(STARTUP_MESSAGE);
			
			prioritySetup();
			
			statusSetup();
			
			permissionSetup();
			
			trackerSetup();
			
			roleSetup();
			
			workflowSetup();
			
			LOGGER.info(END_MESSAGE);
		}
	}

	public void prioritySetup() {
		if (Priority.countPrioritys() == 0) {
			LOGGER.info("\n\nStart loading Priorities");
			Priority aNew;
			aNew = new Priority();
			aNew.setIsDefault(true);
			aNew.setName("Normal");
			aNew.setPriorityPosition(2);
			Priority.entityManager().persist(aNew);
			aNew = new Priority();
			aNew.setIsDefault(false);
			aNew.setName("Baixa");
			aNew.setPriorityPosition(1);
			Priority.entityManager().persist(aNew);
			aNew = new Priority();
			aNew.setIsDefault(false);
			aNew.setName("Alta");
			aNew.setPriorityPosition(3);
			Priority.entityManager().persist(aNew);
			aNew = new Priority();
			aNew.setIsDefault(false);
			aNew.setName("Urgente");
			aNew.setPriorityPosition(4);
			Priority.entityManager().persist(aNew);
		}
	}

	public void statusSetup() {
		if (IssueStatus.countIssueStatuses() == 0) {
			LOGGER.info("\n\nStart loading Stati");
			IssueStatus aNew;
			aNew = new IssueStatus();
			aNew.setDefaultDoneRatio(0);
			aNew.setIsClosed(false);
			aNew.setIsDefault(true);
			aNew.setName("Novo");
			IssueStatus.entityManager().persist(aNew);
			statusMap.put("Novo", aNew);
			aNew = new IssueStatus();
			aNew.setDefaultDoneRatio(40);
			aNew.setIsClosed(false);
			aNew.setIsDefault(false);
			aNew.setName("Em Andamento");
			IssueStatus.entityManager().persist(aNew);
			statusMap.put("Em Andamento", aNew);
			aNew = new IssueStatus();
			aNew.setDefaultDoneRatio(80);
			aNew.setIsClosed(false);
			aNew.setIsDefault(false);
			aNew.setName("Resolvido");
			IssueStatus.entityManager().persist(aNew);
			statusMap.put("Resolvido", aNew);
			aNew = new IssueStatus();
			aNew.setDefaultDoneRatio(100);
			aNew.setIsClosed(true);
			aNew.setIsDefault(false);
			aNew.setName("Fechado");
			IssueStatus.entityManager().persist(aNew);
			statusMap.put("Fechado", aNew);
			aNew = new IssueStatus();
			aNew.setDefaultDoneRatio(100);
			aNew.setIsClosed(true);
			aNew.setIsDefault(false);
			aNew.setName("Cancelado");
			IssueStatus.entityManager().persist(aNew);
			statusMap.put("Cancelado", aNew);
		}
	}

	public void permissionSetup() {
		if (Permission.countPermissions() == 0) {
			LOGGER.info("\n\nStart loading Permissions");
			String[] permissions = { "PROJETO", "STATUS", "PRIORIDADE",
					"PAPEL", "USUARIO", "TIPO_TAREFA", "FLUXO", "TAREFA",
					"PERMISSAO", "MEMBRO" };
			Permission aNew;
			for (String name : permissions) {
				aNew = new Permission();
				aNew.setName(name);
				Permission.entityManager().persist(aNew);
				permissionMap.put(name, aNew);
			}
		}
	}

	public void trackerSetup() {
		if (Tracker.countTrackers() == 0) {
			LOGGER.info("\n\nStart loading Trackers");
			String[] trackers = { "Tarefa", "Defeito", "Funcionalidade" };
			Tracker aNew;
			for (String name : trackers) {
				aNew = new Tracker();
				aNew.setName(name);
				Tracker.entityManager().persist(aNew);
				trackerMap.put(name, aNew);
			}
		}
	}

	public void roleSetup() {
		if (ProjectRole.countProjectRoles() == 0 && permissionMap.size() > 0) {
			LOGGER.info("\n\nStart loading Roles");
			List<Permission> managerPermissions = Arrays
					.asList(new Permission[] { permissionMap.get("PROJETO"),
							permissionMap.get("MEMBRO"),
							permissionMap.get("TAREFA") });
			ProjectRole aNew;
			aNew = new ProjectRole();
			aNew.setName("Administrador");
			aNew.getPermissions().addAll(permissionMap.values());
			aNew.getPermissions().removeAll(managerPermissions);
			ProjectRole.entityManager().persist(aNew);
			roleMap.put("Administrador", aNew);
			aNew = new ProjectRole();
			aNew.setName("Gerente");
			aNew.getPermissions().addAll(managerPermissions);
			ProjectRole.entityManager().persist(aNew);
			roleMap.put("Gerente", aNew);
			aNew = new ProjectRole();
			aNew.setName("Analista");
			aNew.getPermissions().add(permissionMap.get("TAREFA"));
			ProjectRole.entityManager().persist(aNew);
			roleMap.put("Analista", aNew);
		}
	}

	public void workflowSetup() {
		if (Workflow.countWorkflows() == 0 && statusMap.size() > 0
				&& roleMap.size() > 0 && trackerMap.size() > 0) {
			LOGGER.info("\n\nStart loading Workflows");
			Workflow aNew;
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Novo"));
			aNew.setNewIssueStatus(statusMap.get("Em Andamento"));
			aNew.setProjectRole(roleMap.get("Analista"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Novo"));
			aNew.setNewIssueStatus(statusMap.get("Em Andamento"));
			aNew.setProjectRole(roleMap.get("Gerente"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Em Andamento"));
			aNew.setNewIssueStatus(statusMap.get("Resolvido"));
			aNew.setProjectRole(roleMap.get("Analista"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Em Andamento"));
			aNew.setNewIssueStatus(statusMap.get("Resolvido"));
			aNew.setProjectRole(roleMap.get("Gerente"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Resolvido"));
			aNew.setNewIssueStatus(statusMap.get("Fechado"));
			aNew.setProjectRole(roleMap.get("Gerente"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Novo"));
			aNew.setNewIssueStatus(statusMap.get("Cancelado"));
			aNew.setProjectRole(roleMap.get("Gerente"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Em Andamento"));
			aNew.setNewIssueStatus(statusMap.get("Cancelado"));
			aNew.setProjectRole(roleMap.get("Gerente"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
			aNew = new Workflow();
			aNew.setOldIssueStatus(statusMap.get("Resolvido"));
			aNew.setNewIssueStatus(statusMap.get("Em Andamento"));
			aNew.setProjectRole(roleMap.get("Gerente"));
			aNew.setTracker(trackerMap.get("Tarefa"));
			Workflow.entityManager().persist(aNew);
		}
	}

	private static final String STARTUP_MESSAGE = "\n##################################################################\n"
			+ "##################################################################\n"
			+ "####                #####                #####                ####\n"
			+ "####                #####                #####                ####\n"
			+ "####    #################    ########    #####    ########    ####\n"
			+ "####    #################    ########    #####    ########    ####\n"
			+ "####                #####                #####                ####\n"
			+ "####                #####                #####                ####\n"
			+ "################    #####    ########    #####    ################\n"
			+ "################    #####    ########    #####    ################\n"
			+ "####                #####    ########    #####    ################\n"
			+ "####                #####    ########    #####    ################\n"
			+ "##################################################################\n"
			+ "##################################################################\n"
			+ "\nSTARTING SAP ONLINE\nCHECKING DEFAULT ENTITIES LOADING\n";
	private static final String END_MESSAGE = "\nDEFAULT ENTITIES LOADED, STARTING SYSTEM\n"
			+ "##################################################################";
}
